;;; packages - package definitions for GNU Guix
;;; Copyright (C) 2016, 2017 ng0
;;;
;;; This program is free software: you can redistribute it and/or modify
;;; it under the terms of the GNU Affero General Public License as
;;; published by the Free Software Foundation, either version 3 of the
;;; License, or (at your option) any later version.
;;;
;;; This program is distributed in the hope that it will be useful,
;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;;; GNU Affero General Public License for more details.
;;;
;;; You should have received a copy of the GNU Affero General Public License
;;; along with this program.  If not, see <http://www.gnu.org/licenses/>.

(define-module (ng0 packages psyc)
  #:use-module ((guix licenses) #:prefix license:)
  #:use-module (guix packages)
  #:use-module (guix download)
  #:use-module (guix git-download)
  #:use-module (guix build-system gnu)
  #:use-module (gnu packages)
  #:use-module (gnu packages admin)
  #:use-module (gnu packages bison)
  #:use-module (gnu packages linux)
  #:use-module (gnu packages pcre)
  #:use-module (gnu packages autotools)
  #:use-module (gnu packages man)
  #:use-module (gnu packages compression)
  #:use-module (gnu packages gettext)
  #:use-module (gnu packages perl)
  #:use-module (gnu packages pkg-config)
  #:use-module (gnu packages tls)
  #:use-module (gnu packages perl)
  #:use-module (gnu packages web)
  #:use-module (guix build-system perl)
  #:use-module (gnu packages ncurses))

;; Outdated, mostly upstreamed now.

(define-public libpsyc
  (package
    (name "libpsyc")
    (version "20160913")
    (source (origin
              (method url-fetch)
              (uri (string-append "http://www.psyced.org/files/"
                                  name "-" version ".tar.xz"))
              (sha256
               (base32
                "14q89fxap05ajkfn20rnhc6b1h4i3i2adyr7y6hs5zqwb2lcmc1p"))))
    (build-system gnu-build-system)
    (native-inputs
     `(("perl" ,perl)
       ("netcat" ,netcat)
       ("procps" ,procps)))
    (arguments
     `(#:make-flags (list "CC=gcc"
                          (string-append "PREFIX=" (assoc-ref %outputs "out")))
       #:phases
       (modify-phases %standard-phases
         (delete 'configure)))) ; no configure script
    (home-page "http://about.psyc.eu/libpsyc")
    (description "libpsyc is a PSYC library in C which implements core aspects of
PSYC, useful for all kinds of clients and servers including psyced.")
    (synopsis "PSYC library in C useful for all kinds of clients and servers")
    (license (list license:agpl3
                   license:public-domain)))) ; test server is based on a public-domain test

(define-public libpsyc-git
  (let ((revision "1")
        (commit "2e82f31f9d9281af0b3450d617458ca85dd12ee5"))
    (package
      (name "libpsyc-git")
      (version (string-append "20160913-" revision "." (string-take commit 7)))
      (source (origin
                (method git-fetch)
                (uri (git-reference
                      (url "git://git.psyced.org/libpsyc")
                      (commit commit)))
                (file-name (string-append name "-" version "-checkout"))
                (sha256
                 (base32
                  "1857l92asyf16gbq0xnb7lb1lfjaki7a4frg7qwvl8rabh9bb9fv"))))
      (build-system gnu-build-system)
      (native-inputs
       `(("perl" ,perl)
         ("netcat" ,netcat)
         ("procps" ,procps)))
      (arguments
       `(#:make-flags (list "CC=gcc"
                            (string-append "PREFIX=" (assoc-ref %outputs "out")))
         #:phases
         (modify-phases %standard-phases
           (delete 'configure)))) ; no configure script
      (home-page "http://about.psyc.eu/libpsyc")
      (description
       "libpsyc is a PSYC library in C which implements core aspects of
PSYC, useful for all kinds of clients and servers including psyced.")
      (synopsis "PSYC library in C useful for all kinds of clients and servers")
      (license (list license:agpl3
                      ;; test server is based on a public-domain test
                     license:public-domain)))))

(define-public psyclpc
  (package
    (name "psyclpc")
    (version "20160821")
    (source (origin
              (method url-fetch)
              (uri (string-append "http://www.psyced.org/files/"
                                  name "-" version ".tar.xz"))
              (sha256
               (base32
                "0c2afcj8b2yr2vmy9sy0528iqs9sw01j6q35lvxicm42gs7vnik2"))))
    (build-system gnu-build-system)
    (arguments
     `(#:tests? #f ; There are no tests/checks.
       #:configure-flags (list
                          "--enable-use-tls=yes"
                          "--enable-use-mccp"
                          (string-append "--with-openssl="
                                         (assoc-ref %build-inputs "openssl"))
                          (string-append "--prefix="
                                         (assoc-ref %outputs "out"))
                          (string-append "--libdir=" ; "-DMUD_LIB="
                                         (assoc-ref %outputs "out")
                                         "/opt/psyced/world")
                          (string-append "--bindir="
                                         (assoc-ref %outputs "out")
                                         "/opt/psyced/bin")
                          (string-append "--libexecdir=" ; "-DERQ_DIR="
                                         (assoc-ref %outputs "out")
                                         "/opt/psyced/run"))
       #:phases
       (modify-phases %standard-phases
         (add-before 'configure 'chdir-to-src
           (lambda _
             (chdir "src")
             (setenv "CONFIG_SHELL" (which "sh"))
             (setenv "SHELL" (which "sh"))))
         (replace 'install
           (lambda _
             (zero? (system* "make" "install-all")))))))
    ;; XXX: let us try openssl first, debug with libressl and upstream
    ;; the one which works. Expectation: both work.
    ;; PCRE is bundled (or was it in psyced?) to stay on a compatible version
    ;; with psyclpc. TODO: unbundle.
    (inputs
     `(("zlib" ,zlib)
       ("openssl" ,openssl)
       ("pcre" ,pcre)))
    (native-inputs
     `(("pkg-config" ,pkg-config)
       ("bison" ,bison)
       ("gnu-gettext" ,gnu-gettext)
       ("help2man" ,help2man)
       ("autoconf" ,autoconf)
       ("automake" ,automake)))
    (home-page "http://lpc.psyc.eu/")
    (synopsis "psycLPC is a multi-user network server programming language")
    (description
     "LPC is a bytecode language, invented to specifically implement
multi user virtual environments on the internet. This technology is used for
MUDs and also the psyced implementation of the Protocol for SYnchronous Conferencing.")
    (license license:gpl2)))

(define-public psyclpc-git
  (let ((revision "1")
        (commit "27f21a3bf0d140f0d2680c695e8df229b46a814b"))
    (package
      (name "psyclpc-git")
      (version (string-append "20160417" revision "." (string-take commit 8)))
      (source (origin
                (method git-fetch)
                (uri (git-reference
                      (url "git://git.psyced.org/git/psyclpc")
                      (commit commit)))
                (file-name (string-append name "-" version "-checkout"))
                (sha256
                 (base32
                  "1m17xyixbh6wfwk727h3cfjmyfplcgvwbgh12kap1856xiqh99c5"))))
      (build-system gnu-build-system)
      (arguments
       `(#:tests? #f
         #:configure-flags (list
                            "--enable-use-tls=yes"
                            "--enable-use-mccp"
                            (string-append "--with-openssl="
                                           (assoc-ref %build-inputs "openssl"))
                            (string-append "--prefix="
                                           (assoc-ref %outputs "out"))
                            (string-append "--libdir=" ; "-DMUD_LIB="
                                           (assoc-ref %outputs "out")
                                           "/opt/psyced/world")
                            (string-append "--bindir="
                                           (assoc-ref %outputs "out")
                                           "/opt/psyced/bin")
                            (string-append "--libexecdir=" ; "-DERQ_DIR="
                                           (assoc-ref %outputs "out")
                                           "/opt/psyced/run"))
         ;; #:make-flags (list
         ;;               (string-append "prefix="
         ;;                              (assoc-ref %outputs "out") "/opt/psyclpc"))
         #:phases
         (modify-phases %standard-phases
           (add-before 'configure 'chdir-to-src
             (lambda _
               (chdir "src")
               (setenv "CONFIG_SHELL" (which "sh"))
               (setenv "SHELL" (which "sh"))))
           (replace 'install
             (lambda _
               (zero? (system* "make" "install-all")))))))
      (inputs
       `(("zlib" ,zlib)
         ("openssl" ,openssl)
         ("pcre" ,pcre)
         ("autoconf" ,autoconf)
         ("automake" ,automake)
         ("perl" ,perl)))
      (native-inputs
       `(("pkg-config" ,pkg-config)
         ("bison" ,bison)
         ("gnu-gettext" ,gnu-gettext)
         ("help2man" ,help2man)))
      (home-page "http://lpc.psyc.eu/")
      (synopsis "psycLPC is a multi-user network server programming language")
      (description
       "LPC is a bytecode language, invented to specifically implement
multi user virtual environments on the internet. This technology is used for
MUDs and also the psyced implementation of the Protocol for SYnchronous Conferencing.")
      (license license:gpl2))))

;; See notes in the section below the header of this file.
;; The tarball is made to fit the current build system of psyced, which we can not
;; use. using a git checkout saves the time to extract something which then
;; holds another archive where the usable data is contained.
;; What applies is: roll your own distribution.
(define-public psyced
  (package
    (name "psyced")
    (version "20160525")
    (source (origin
              (method url-fetch)
              (uri (string-append "http://www.psyced.org/files/"
                                  name "-" version ".tar.bz2"))
              (sha256
               (base32
                "084fzl9x20r3wqkmh4125fydaj2dgrazp11ddh8cb48sczsiksak"))))
    (build-system gnu-build-system)
    ;; The install.sh is interactive, guix build can not make use of this.
    ;; Much of what install.sh used to do is now handled by psyconf.
    (propagated-inputs
     `(("psyclpc" ,psyclpc)
       ("perl" ,perl)))
    (native-inputs
     `(("pkg-config" ,pkg-config)))
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (replace 'install
           (lambda _
             (system* "./install.sh"))))))
    (home-page "http://www.psyced.org")
    (synopsis "Server for Federated Messaging and Chat over PSYC, IRC, XMPP, and more")
    (description
     "LPC is a bytecode language, invented to specifically implement
multi user virtual environments on the internet. This technology is used for
MUDs and also the psyced implementation of the Protocol for SYnchronous Conferencing.")
    (license license:gpl2)))

(define-public psyced-git
  (let* ((commit "18e72b74ccc4edef58751475d15138fb1300a3b1")
         (revision "1"))
    (package
      (name "psyced-git")
      (version (string-append "20160830-" revision "." (string-take commit 7)))
      (source (origin
                (method git-fetch)
                (uri (git-reference
                      (url "git://git.psyced.org/psyced")
                      (commit commit)))
                (file-name (string-append name "-" version "-checkout"))
                (sha256
                 (base32
                  "1h2cbb14lvnxyqf9g35h78d796hyhafg3h73jv69z6j2cvhka9r2"))))
      (build-system gnu-build-system)
      ;; The install.sh (provided with the tarball) is interactive,
      ;; Guix build can not make use of this.
      ;; Much of what install.sh used to do is now handled by psyconf anyway.
      (inputs
       `(("psyclpc" ,psyclpc) ; propagated-inputs? It is needed at runtime.
         ("perl" ,perl)))
      (native-inputs
       `(("pkg-config" ,pkg-config)))
      (arguments
       `(#:tests? #f
         #:phases
         (modify-phases %standard-phases
           (delete 'configure)
           (delete 'build) ; no make build needed
           (replace 'install
             (lambda* (#:key outputs #:allow-other-keys)
               (let* ((out (assoc-ref outputs "out"))
                      (bin (string-append out "/bin")) ;symlink it?
                      (doc (string-append out "/share/doc"))
                      (opt (string-append out "/opt/psyced")) ;sandbox is in /opt/psyced/world
                      (var (string-append out "/var/psyced"))
                      (vard (string-append var "/data"))
                      (vardpe (string-append vard "/person"))
                      (vardpl (string-append vard "/place"))
                      (varcon (string-append var "/config"))
                      (etcpsy (string-append out "/etc/psyc")) ;symlink to /
                      (varlp (string-append out "/var/log/psyced")) ;symlink to /
                      (varlpp (string-append varlp "/place"))) ;symlink to /
                 ;; Create directories...
                 (mkdir-p bin)
                 (mkdir-p doc)
                 (mkdir-p opt)
                 (mkdir-p var)
                 (mkdir-p vard)
                 (mkdir-p vardpe)
                 (mkdir-p vardpl)
                 (mkdir-p varcon)
                 (mkdir-p etcpsy)
                 (mkdir-p varlp)
                 (mkdir-p varlpp)
                 ;; copy binaries
                 (copy-recursively "bin" bin)
                 ;; copy config
                 (install-file "config/psyced.ini" etcpsy)
                 ;; (install-file '("AGENDA.txt" "CHANGESTODO" "COPYLEFT.txt" "FIRSTSTEPS.txt"
                 ;;                 "LICENSE.txt" "README.txt") doc)
                 ;; (copy-recursively '("pike" "place" "run" "tor" "config"
                 ;;                     "trust" "utility" "world") opt)
                 ;; ;; replace this with a for-each something:
                 (install-file "AGENDA.txt" doc)
                 (install-file "CHANGESTODO" doc)
                 (install-file "COPYLEFT.txt" doc)
                 ;;(install-file "FIRSTSTEPS.txt" doc)
                 (install-file "LICENSE.txt" doc)
                 ;;(install-file "README.txt" doc)
                 (copy-recursively "pike" opt)
                 (copy-recursively "place" opt)
                 (copy-recursively "run" opt)
                 (copy-recursively "tor" opt)
                 (copy-recursively "config" opt)
                 (copy-recursively "trust" opt)
                 (copy-recursively "utility" opt)
                 (copy-recursively "world" opt)
                 #t)))
           (add-after 'install 'wrap-programs
             (lambda* (#:key outputs #:allow-other-keys)
               ;; Make sure all executables in "bin" find the Perl modules
               ;; provided by this package at runtime.
               (let* ((out  (assoc-ref outputs "out"))
                      (bin  (string-append out "/bin/"))
                      (path (string-append out "/lib/perl5/site_perl")))
                 (for-each (lambda (file)
                             (wrap-program file
                               `("PERL5LIB" ":" prefix (,path))))
                           (find-files bin "\\.*$"))
                 #t))))))
      (home-page "http://www.psyced.org")
      (synopsis "Server for Federated Messaging and Chat over PSYC, IRC, XMPP, and more")
      (description
       "LPC is a bytecode language, invented to specifically implement
multi user virtual environments on the internet. This technology is used for
MUDs and also the psyced implementation of the Protocol for SYnchronous Conferencing.")
      (license license:gpl2))))

;; Send upstream, inclusion pending.
(define-public perl-net-psyc
  (package
    (name "perl-net-psyc")
    (version "1.1")
    (source (origin
              (method url-fetch)
              (uri (string-append "http://perl.psyc.eu/"
                                  "perlpsyc-" version ".zip"))
              (file-name (string-append name "-" version ".zip"))
              (sha256
               (base32
                "1lw6807qrbmvzbrjn1rna1dhir2k70xpcjvyjn45y35hav333a42"))
              ;; psycmp3 currently depends on MP3::List and rxaudio (shareware),
              ;; we can add it back when this is no longer the case.
              (snippet '(delete-file "contrib/psycmp3"))))
    (build-system perl-build-system)
    (inputs
     `(("perl-curses" ,perl-curses)
       ("perl-io-socket-ssl" ,perl-io-socket-ssl)))
    (arguments
     `(#:phases
       (modify-phases %standard-phases
         (delete 'configure) ; No configure script
         ;; There is a Makefile, but it does not install everything
         ;; (leaves out psycion) and says
         ;; "# Just to give you a rough idea". XXX: Fix it upstream.
         (delete 'build)
         (add-before 'build 'build-manuals
           (lambda _
             (zero? (system* "make" "manuals"))))
         (replace 'install
           (lambda* (#:key outputs #:allow-other-keys)
             (let* ((out (assoc-ref outputs "out"))
                    (doc (string-append out "/share/doc/perl-net-psyc"))
                    (man (string-append out "/share/man"))
                    (bin (string-append out "/bin"))
                    (libpsyc (string-append out "/lib/psyc/ion"))
                    (libperl (string-append out "/lib/perl5/site_perl/"
                                            ,(package-version perl))))

               (copy-recursively "lib/perl5" libperl)
               (copy-recursively "lib/psycion" libpsyc)
               (copy-recursively "bin" bin)
               (install-file "cgi/psycpager" (string-append doc "/cgi"))
               (copy-recursively "contrib" (string-append doc "/contrib"))
               (copy-recursively "hooks" (string-append doc "/hooks"))
               (copy-recursively "sdj" (string-append doc "/sdj"))
               (install-file "README.txt" doc)
               (install-file "TODO.txt" doc)
               (copy-recursively "share/man/man1" (string-append man "/man1"))
               (copy-recursively "share/man/man3" (string-append man "/man3"))
               #t)))
         (add-after 'install 'wrap-programs
           (lambda* (#:key outputs #:allow-other-keys)
             ;; Make sure all executables in "bin" find the Perl modules
             ;; provided by this package at runtime.
             (let* ((out  (assoc-ref outputs "out"))
                    (bin  (string-append out "/bin/"))
                    (path (getenv "PERL5LIB")))
               (for-each (lambda (file)
                           (wrap-program file
                             `("PERL5LIB" ":" prefix (,path))))
                         (find-files bin "\\.*$"))
               #t))))))
    (description
     "@code{Net::PSYC} with support for TCP, UDP, Event.pm, @code{IO::Select} and
Gtk2 event loops.  This package includes 12 applications and additional scripts:
psycion, a @uref{http://about.psyc.eu,PSYC} chat client, remotor, a control console
for @uref{https://torproject.org,tor} router, and many more.")
    (synopsis "Perl implementation of PSYC protocol")
    (home-page "http://perlpsyc.pages.de")
    (license (list license:gpl2 (package-license perl)
                   ;; contrib/irssi-psyc.pl
                   license:public-domain
                   ;; bin/psycplay states AGPL with no version
                   license:agpl3+))))
